package itdep.ui.components.address;

import ga.tapestry.internal.SelectModelBuilder;
import itdep.domain.address.City;
import itdep.domain.address.Country;
import itdep.domain.address.District;
import itdep.domain.address.Region;
import itdep.services.address.CountryService;
import org.apache.tapestry5.SelectModel;
import org.apache.tapestry5.annotations.Component;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.corelib.components.Select;
import org.apache.tapestry5.corelib.components.Zone;
import org.apache.tapestry5.ioc.annotations.Inject;

import java.util.List;
import java.util.Set;

/**
 * @author Ivan Khalopik
 * @version $Revision: 47 $ $Date: 2010-07-05 09:28:44 +0000 (Mon, 05 Jul 2010) $
 */
public class CitySelect {

	@Property
	@Parameter(required = true)
	private City value;

	@Property
	@Parameter
	private boolean editable;

	@Inject
	private CountryService countryService;

	@Inject
	private SelectModelBuilder selectModelBuilder;

	@Component
	private Zone selectCityZone;

	@Component(
			parameters = {
					"value=country",
					"model=countryModel",
					"zone=selectCityZone"})
	private Select countrySelect;

	@Component(
			parameters = {
					"value=region",
					"model=regionModel",
					"zone=selectCityZone"})
	private Select regionSelect;

	@Component(
			parameters = {
					"value=district",
					"model=districtModel",
					"zone=selectCityZone"})
	private Select districtSelect;

	@Component(
			parameters = {
					"value=value",
					"model=cityModel"})
	private Select citySelect;

	@Property
	private Country country;

	@Property
	private Region region;

	@Property
	private District district;

	private SelectModel countryModel;
	private SelectModel regionModel;
	private SelectModel districtModel;
	private SelectModel cityModel;

	public SelectModel getCountryModel() {
		if (countryModel == null) {
			final List<Country> countries = countryService.getEntities();
			countryModel = selectModelBuilder.buildFormatted(Country.class, countries, "%s", Country.NAME_PROPERTY);
		}
		return countryModel;
	}

	public SelectModel getRegionModel() {
		if (regionModel == null) {
			if (country != null) {
				final Set<Region> regions = country.getRegions();
				regionModel = selectModelBuilder.buildFormatted(Region.class, regions, "%s", Region.NAME_PROPERTY);
			} else {
				regionModel = selectModelBuilder.buildEmpty();
			}
		}
		return regionModel;
	}

	public SelectModel getDistrictModel() {
		if (districtModel == null) {
			if (region != null) {
				final Set<District> districts = region.getDistricts();
				districtModel = selectModelBuilder.buildFormatted(District.class, districts, "%s", District.NAME_PROPERTY);
			} else {
				districtModel = selectModelBuilder.buildEmpty();
			}
		}
		return districtModel;
	}

	public SelectModel getCityModel() {
		if (cityModel == null) {
			if (district != null) {
				final Set<City> cities = district.getCities();
				districtModel = selectModelBuilder.buildFormatted(City.class, cities, "%s", City.NAME_PROPERTY);
			} else {
				districtModel = selectModelBuilder.buildEmpty();
			}
		}
		return districtModel;
	}

	void setupRender() {
		district = value != null ? value.getDistrict() : null;
		region = district != null ? district.getRegion() : null;
		country = region != null ? region.getCountry() : null;
	}

	Object onValueChangedFromCountrySelect(Country countryValue) {
		country = countryValue;
		regionModel = null;
		return onValueChangedFromRegionSelect(null);
	}

	Object onValueChangedFromRegionSelect(Region regionValue) {
		region = regionValue;
		districtModel = null;
		return onValueChangedFromDistrictSelect(null);
	}

	Object onValueChangedFromDistrictSelect(District districtValue) {
		value = null;
		district = districtValue;
		if (district != null) {
			region = district.getRegion();
		}
		if (region != null) {
			country = region.getCountry();
		}
		cityModel = null;
		return selectCityZone.getBody();
	}
}